﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StyleMVVM.DependencyInjection;
using StyleMVVM.ViewModel;
using Windows.Foundation;
using Windows.UI.Xaml;

namespace StyleMVVM.View.Regions
{
	public class BaseRegionAdapter<T> : IRegionAdapter
	{
		[Import]
		public IDependencyInjectionContainer Container { get; set; }

		public virtual IEnumerable<object> GetCurrentExports(IRegion region, object control)
		{
			return new List<object>();
		}

		public Type AddapterType
		{
			get { return typeof(T); }
		}

		public IAsyncOperation<bool> Activate(IRegion region, object control, string newExport)
		{
			return Activate(region, (T)control, newExport).AsAsyncOperation();
		}

		public IAsyncOperation<bool> Deactivate(IRegion region, object control, string newExport)
		{
			return Deactivate(region, (T)control, newExport).AsAsyncOperation();
		}

		public IAsyncOperation<bool> Navigate(IRegion region, object control, string newExport, object navigationParameter)
		{
			return Navigate(region, (T)control, newExport, navigationParameter).AsAsyncOperation();
		}

		public IAsyncOperation<bool> Add(IRegion region, object control, string newExportName, object navigationParameter)
		{
			return Add(region, (T)control, newExportName, navigationParameter).AsAsyncOperation();
		}

		public IAsyncOperation<bool> Add(IRegion region, object control, object newExport, object navigationParameter)
		{
			return Add(region, (T)control, newExport, navigationParameter).AsAsyncOperation();
		}

		public IAsyncOperation<bool> Remove(IRegion region, object control, string oldExportName)
		{
			return Remove(region, (T)control, oldExportName).AsAsyncOperation();
		}

		public IAsyncOperation<bool> Remove(IRegion region, object control, object oldExport)
		{
			return Remove(region, (T)control, oldExport).AsAsyncOperation();
		}

		protected virtual async Task<bool> Activate(IRegion region, T control, string newExport)
		{
			return false;
		}

		protected virtual async Task<bool> Deactivate(IRegion region, T control, string newExport)
		{
			return false;
		}

		protected virtual async Task<bool> Navigate(IRegion region, T control, string newExport, object navigationParameter)
		{
			return false;
		}

		protected virtual async Task<bool> Add(IRegion region, T control, string newExportName, object navigationParameter)
		{
			return false;
		}

		protected virtual async Task<bool> Add(IRegion region, T control, object newExport, object navigationParameter)
		{
			return false;
		}

		protected virtual async Task<bool> Remove(IRegion region, T control, string oldExportName)
		{
			return false;
		}

		protected virtual async Task<bool> Remove(IRegion region, T control, object oldExport)
		{
			return false;
		}

		protected async Task<bool> CallNavigatingFrom(IRegion region, FrameworkElement oldExport)
		{
			if (oldExport != null && oldExport.DataContext is INavigationViewModel)
			{
				INavigationViewModel navigationViewModel = oldExport.DataContext as INavigationViewModel;

				StyleNavigatingCancelEventArgs args = new StyleNavigatingCancelEventArgs();

				await navigationViewModel.NavigatingFrom(oldExport, args);

				return args.Cancel;
			}

			return false;
		}

		protected void CallNavigatedTo(IRegion region, FrameworkElement newExport, object navigationParameter)
		{
			if (newExport != null)
			{
				IRegionAware regionAware = newExport.DataContext as IRegionAware;

				if (regionAware != null)
				{
					regionAware.Region = region;
				}

				if (newExport.DataContext is INavigationViewModel)
				{
					INavigationViewModel navigationViewModel = newExport.DataContext as INavigationViewModel;

					navigationViewModel.NavigationParameter = navigationParameter;

					navigationViewModel.NavigatedTo(newExport, new StyleNavigationEventArgs());
				}
			}
		}

		protected void CallNavigatedFrom(IRegion region, FrameworkElement oldExport)
		{
			if (oldExport != null)
			{
				IRegionAware regionAware = oldExport.DataContext as IRegionAware;

				if (regionAware != null)
				{
					regionAware.Region = region;
				}

				INavigationViewModel navigationViewModel = oldExport.DataContext as INavigationViewModel;

				if (navigationViewModel != null)
				{
					navigationViewModel.NavigatedFrom(oldExport, null);
				}
			}
		}
	}
}